package com.diyunapp.xilinapp.utils;

/**
* 
* 上传工具类
* 支持上传文件和参数
*/

import android.util.Log;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

public class UploadUtil {

	private static UploadUtil uploadUtil;
	private static final String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成
	private static final String PREFIX = "--";
	private static final String LINE_END = "\r\n";
	private static final String CONTENT_TYPE = "multipart/form-data"; // 内容类型
	private UploadUtil() {

	}

	/**
	* 单例模式获取上传工具类
	* @return
	*/
	public static UploadUtil getInstance() {
		if (null == uploadUtil) {
			uploadUtil = new UploadUtil();
		}
		return uploadUtil;
	}

	private static final String TAG = "UploadUtil";
	private int readTimeOut = 10 * 1000; // 读取超时
	private int connectTimeout = 10 * 1000; // 超时时间
	/***
	* 请求使用多长时间
	*/
	private static int requestTime = 0;

	private static final String CHARSET = "utf-8"; // 设置编码

	/***
	* 上传成功
	*/
	public static final int UPLOAD_SUCCESS_CODE = 0;
	/***
	* 上传中
	*/
	public static final int UPLOAD_ING_CODE = 1;
	/**
	* 文件不存在
	*/
	public static final int UPLOAD_FILE_NOT_EXISTS_CODE = 2;
	/**
	* 服务器出错
	*/
	public static final int UPLOAD_SERVER_ERROR_CODE = 3;
	protected static final int WHAT_TO_UPLOAD = 1;
	protected static final int WHAT_UPLOAD_DONE = 2;

	/**
	* android上传文件到服务器
	* 
	* @param filePath
	* 需要上传的文件的路径
	* @param fileKey
	* 在网页上<input type=file name=xxx/> xxx就是这里的fileKey
	* @param RequestURL
	* 请求的URL
	*/
	public void uploadFile(final String filePath, final String RequestURL,final Map<String, String> params) {
		if (filePath == null) {
			sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE,"文件不存在");
			return;
		}
		try {
			Log.i(TAG, "请求的URL=" + RequestURL);
			File file = new File(filePath);
			Log.i(TAG, "请求的fileName=" + file.getName());
			new Thread(new Runnable() { //开启线程上传文件
					@Override
					public void run() {
						toUploadFile(filePath, RequestURL,params);
					}
				}).start();
		} 
		catch (Exception e) {
			sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE,"文件不存在");
			e.printStackTrace();
			return;
		}
	}
	
  /* 上传文件至Server，uploadUrl：接收文件的处理页面 */
  private void toUploadFile(String srcPath,String RequestURL,Map<String, String> params)
  {
    String end = "\r\n";
    String twoHyphens = "--";
    String boundary = "******";
    try
    {
      URL url = new URL(RequestURL);
      HttpURLConnection httpURLConnection = (HttpURLConnection) url
          .openConnection();
      // 设置每次传输的流大小，可以有效防止手机因为内存不足崩溃
      // 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。
      //httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
      // 允许输入输出流
      httpURLConnection.setDoInput(true);
      httpURLConnection.setDoOutput(true);
      httpURLConnection.setUseCaches(false);
      // 使用POST方法
      httpURLConnection.setRequestMethod("POST");
      httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
      httpURLConnection.setRequestProperty("Charset", "UTF-8");
      httpURLConnection.setRequestProperty("Content-Type",
          "multipart/form-data;boundary=" + boundary);

      DataOutputStream dos = new DataOutputStream(
          httpURLConnection.getOutputStream());
      dos.writeBytes(twoHyphens + boundary + end);
      dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\""
          + srcPath.substring(srcPath.lastIndexOf("/") + 1)
          + "\""
          + end);
      dos.writeBytes(end);

      FileInputStream fis = new FileInputStream(srcPath);
      byte[] buffer = new byte[8192]; // 8k
      int count = 0;
      long total = 0;
      // 读取文件
      while ((count = fis.read(buffer)) != -1)
      {
        dos.write(buffer, 0, count);
        total += count;
        sendMessage((int)(total/1024));
      }
      fis.close();

      dos.writeBytes(end);
      
      Set<String> keySet = params.keySet();
      for (Iterator<String> it = keySet.iterator(); it.hasNext();)
      {
		  String name = it.next();
		  String value = params.get(name);
		  dos.writeBytes(twoHyphens + boundary + end);
		  dos.writeBytes("Content-Disposition: form-data; name=\"" + name +"\""+ end);
		  dos.writeBytes(end);
		  dos.writeBytes(value + end);
		  //dos.writeBytes(URLEncoder.encode(value, "UTF-8")+ end);
      }
	  
      dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
      dos.flush();
      InputStream is = httpURLConnection.getInputStream();
      InputStreamReader isr = new InputStreamReader(is, "utf-8");
      BufferedReader br = new BufferedReader(isr);
      String result = br.readLine();

      Log.i("zhangxiaoxidebug", "upload picture result = " +result);
      dos.close();
      is.close();
      JSONObject upresult = new JSONObject(result);
      if(upresult.getInt("status")==1)
      {
    	  sendMessage(UPLOAD_SUCCESS_CODE, "上传成功");
      }
      else
      {
    	  String show_err = upresult.getString("message");
    	  sendMessage(UPLOAD_SERVER_ERROR_CODE, show_err);
      }
    } catch (Exception e){
    	sendMessage(UPLOAD_SERVER_ERROR_CODE, "上传失败！");
      e.printStackTrace();
    }
  }
	
	
	/**
	* 发送上传结果
	* @param responseCode
	* @param responseMessage
	*/
	private void sendMessage(int responseCode,String responseMessage)
	{
		onUploadProcessListener.onUploadDone(responseCode, responseMessage);
	}
	
	/**
	* 发送传输进度
	* @param responseCode
	* @param responseMessage
	*/
	private void sendMessage(int progress)
	{
		onUploadProcessListener.onUploadProcess(progress);
	}

	/**
	* 下面是一个自定义的回调函数，用到回调上传文件是否完成
	* 
	* 
	*/
	public static interface OnUploadProcessListener {
		/**
		* 上传响应
		* @param responseCode
		* @param message
		*/
		void onUploadDone(int responseCode, String message);
		/**
		* 上传中
		* @param uploadSize
		*/
		void onUploadProcess(int uploadSize);
		/**
		* 准备上传
		* @param fileSize
		*/
		void initUpload(int fileSize);
	}
	
	private OnUploadProcessListener onUploadProcessListener;

	public void setOnUploadProcessListener(
			OnUploadProcessListener onUploadProcessListener) {
		this.onUploadProcessListener = onUploadProcessListener;
	}

	public int getReadTimeOut() {
		return readTimeOut;
	}

	public void setReadTimeOut(int readTimeOut) {
		this.readTimeOut = readTimeOut;
	}

	public int getConnectTimeout() {
		return connectTimeout;
	}

	public void setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
	}
	/**
	* 获取上传使用的时间
	* @return
	*/
	public static int getRequestTime() {
		return requestTime;
	}

	public static interface uploadProcessListener{

	}
}
